<!--
 * @Author: anshengtyp
 * @Date: 2024-03-11 11:22:01
 * @LastEditTime: 2024-08-21 08:33:16
 * @LastEditors: anshengtyp 1815634838@qq.com
 * @Description: 预览
-->
<template>
  <div v-if="isShow" style="width: 100%;height: 100%;" id="preview720">
    <!--返回按钮 -->
    <el-icon class="icon" v-show="fullId.length > 1" title="返回" @click="goBack">
      <ArrowLeftBold></ArrowLeftBold>
    </el-icon>
  </div>
  <el-empty v-else style="width: 100%;height: 100%;" description="该照片未发布" />
</template>

<script setup>
import { Viewer } from '@photo-sphere-viewer/core';
import { ElMessage } from 'element-plus'
import { MarkersPlugin } from '@photo-sphere-viewer/markers-plugin';
import { EquirectangularTilesAdapter } from '@photo-sphere-viewer/equirectangular-tiles-adapter';
import { CubemapTilesAdapter } from '@photo-sphere-viewer/cubemap-tiles-adapter';
import cache from '@/plugins/cache'
import "@photo-sphere-viewer/core/index.css"
import "@photo-sphere-viewer/markers-plugin/index.css"
import { onMounted, ref, watch } from 'vue';
import { pictPreview } from "@/api/index";
let viewer = ref(null);
let markersPlugin = ref(null);
let markers = ref([]);
let url = ref('');
let fullId = ref([]);
let allData = ref(null);
let panoramaObj = ref(null);
let pictType = ref(null);
let isShow = ref(true);
onMounted(async () => {
  if (cache.session.getJSON('fullId')) {
    fullId.value = cache.session.getJSON('fullId');
  }
  await getData();
  if (isShow.value) {
    init();
  }
})

async function getData() {
  const urlParams = new URLSearchParams(window.location.search);
  const id = urlParams.get('id');
  const res = await pictPreview(id);
  if (res.data?.status === '0') {
    // 不是后台同时数据未发布
    isShow.value = false;
    return;
  }
  allData.value = res.data;
  if (res.data) {
    fullId.value.push(id);
    fullId.value = [...new Set(fullId.value)]; // 去重
    cache.session.setJSON('fullId', fullId.value);
  } else {
    changeUrl('id', fullId.value.at(-1));
  }
  if (res.data) {
    res.data.pictureType === '0' ? pictType.value = EquirectangularTilesAdapter : pictType.value = CubemapTilesAdapter;
    url.value = import.meta.env.VITE_APP_PIC_BASE_API + res.data.thumb.path;
  }
  if (res.data?.annotation) {
    markers.value = JSON.parse(res.data.annotation);
  } else {
    markers.value = [];
  }
  // 平面
  if (res.data?.pictureType === '0') {
    panoramaObj.value = {
      width: allData.value.tilesValue.width,
      cols: allData.value.tilesValue.cols,
      rows: allData.value.tilesValue.rows,
      baseUrl: url.value,
      tileUrl: (col, row) => {
        const tileIdentifier = `${row}_${col}`;
        const item = allData.value.tilesValue.files[tileIdentifier];
        return import.meta.env.VITE_APP_PIC_BASE_API + '/' + allData.value.tilesValue.folder + '/' + item;
      }
    }
  } else if (res.data?.pictureType === '1') {
    // 立体
    Object.keys(allData.value.cubeValue).forEach(key => {
      allData.value.cubeValue[key] = import.meta.env.VITE_APP_PIC_BASE_API + allData.value.cubeValue[key];
    })
    panoramaObj.value = {
      faceSize: allData.value.cubeTilesValue.file[0].width,
      nbTiles: 8,
      baseUrl: allData.value.cubeValue,
      tileUrl: (face, col, row) => {
        let key = allData.value.cubeValue[face].split('/').at(-1).split('.')[0] // 文件名称
        let target = allData.value.cubeTilesValue.file.find(item => item.folder.indexOf(key) > -1);
        const tileIdentifier = `${row}_${col}`;
        const item = target.files[tileIdentifier];
        return import.meta.env.VITE_APP_PIC_BASE_API + '/' + target.folder + '/' + item;
      }
    }
  }
}

function init() {
  const config = {
    container: 'preview720',
    adapter: pictType.value,
    panorama: panoramaObj.value,
    touchmoveTwoFingers: false,
    size: {
      height: '100%',
      width: '100%'
    },
    moveSpeed: 2,
    zoomSpeed: 10,
    navbar: [ // 底部导航栏，依次是自动播放、缩放、图库、文字、全屏
      'zoom',
      'move',
      'download',
      'description',
      'caption',
      'fullscreen',
    ],
    plugins: [
      [
        MarkersPlugin,
        {
          markers: []
        }
      ]
    ]
  }
  viewer.value = new Viewer(config);

  // 全景图加载完成时的回调。获取标注数据
  viewer.value.addEventListener('ready', () => {
    initMarkers();
    btnConfig();
  });
  markersPlugin.value = viewer.value.getPlugin(MarkersPlugin); // 获取标注插件

  markersPlugin.value.addEventListener('select-marker', ({ marker }) => {
    if (marker.config.type === '全景') {
      // 全景跳转
      fullViewGo(marker);
    }
  });
}

// 初始化标注
function initMarkers() {
  if (!markers.value.length) return;
  markers.value.forEach(item => {
    markersPlugin.value.addMarker(item.config);
  })
}

function btnConfig() {
  viewer.value.setOption('fisheye', allData.value.detailsValue.enableFisheye);
  viewer.value.setOption('mousewheelCtrlKey', allData.value.detailsValue?.enableCtrlZoom);
  viewer.value.setOption('mousemove', allData.value.detailsValue?.enableMouseInteraction);
  viewer.value.setOption('minFov', allData.value.detailsValue?.minViewAngle);
  viewer.value.setOption('maxFov', allData.value.detailsValue?.maxViewAngle);
  viewer.value.setOption('mousewheel', allData.value.detailsValue?.enableMouseWheel);
  viewer.value.setOption('caption', allData.value.name);
  viewer.value.setOption('description', allData.value.remark);

  viewer.value.rotate({
    yaw: allData.value.detailsValue?.defaultVerticalAngle || 0,
    pitch: allData.value.detailsValue?.defaultHorizontalAngle || 0
  })
  viewer.value.setOption('sphereCorrection', { pan: allData.value.detailsValue?.correctPan, tilt: allData.value.detailsValue.correctTilt, roll: allData.value.detailsValue?.correctRoll });
  viewer.value.zoom(allData.value.detailsValue?.fullscreenButton);
  allData.value.detailsValue.name = allData.value.name;
  allData.value.detailsValue.remark = allData.value.remark;
  let target = {
    moveButton: 'move',
    zoomButton: 'zoom',
    downloadButton: 'download',
    remark: 'description',
    name: 'caption',
    fullscreenButton: 'fullscreen',
  }
  let arr = [];
  for (const key in target) {
    if (allData.value.detailsValue[key]) {
      arr.push(target[key]);
      viewer.value.setOption('navbar', arr); // 动态隐藏导航栏工具
    } else if (!arr.length) {
      viewer.value.setOption('navbar', []); // 动态隐藏导航栏工具
    }
  }
}

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    return uri + separator + key + "=" + value;
  }
}

function changeUrl(key, value) {
  let newUrl = updateQueryStringParameter(window.location.href, key, value); // 修改地址栏参数
  window.history.replaceState({ path: newUrl }, '', newUrl);
}

// 跳转
async function fullViewGo(data) {
  changeUrl('id', data.config?.link || data.id);
  await getData();
  if (!allData.value) return ElMessage.error('跳转照片不存在！');
  markersPlugin.value.clearMarkers();
  viewer.value.destroy();
  if (isShow.value) {
    init();
  }
}

// 返回全景
async function goBack() {
  fullId.value.pop();
  const id = fullId.value.at(-1);
  fullViewGo({ id })
}
</script>

<style lang="scss" scoped>
#preview720 {
  position: relative;

  .icon {
    position: absolute;
    left: 10px;
    top: 10px;
    z-index: 99;
    font-size: 30px;
    cursor: pointer;
  }
}

::v-deep .psv-tooltip {
  max-width: 1000px !important;
}

::v-deep .psv-fullscreen-button {
  position: absolute;
  right: 10px;
}

::v-deep .marker-tooltip-container {
  width: 300px;
  // height: 250px;
  position: relative;
  overflow: hidden;

  .marker-title {
    font-size: 18px;
    font-weight: bold;
    white-space: break-word;
  }

  .marker-description {
    word-wrap: break-word;
  }

  .scroll-container {
    height: 150px;
    width: 100%;
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;

    .tooltipImage {
      width: 300px;
      height: 150px;
      object-fit: cover;
    }
  }
}

::v-deep .psv-loader-text {
  color: black;
}
</style>
